package redis

import (
	"fmt"
	"new_for_deepseek_rabbitmq/config"
	"sync"
	"time"

	"github.com/go-redis/redis"
)

// Redis错误定义
var (
	Nil = redis.Nil // redis空值错误
)

// 全局变量定义
var (
	instance *Redis    // Redis单例实例
	once     sync.Once // 确保只初始化一次的同步原语
)

// Redis配置结构体
type RedisConfig struct {
	Host     string // 主机地址
	Port     int    // 端口
	Password string // 密码
	DB       int    // 库编号
}

// Redis连接选项
type Options struct {
	PoolSize     int
	MinIdleConns int
	IdleTimeout  time.Duration
}

// Redis 结构体封装了Redis连接和并发控制
type Redis struct {
	Client *redis.Client // redis客户端实例
	mu     sync.RWMutex  // 读写锁，用于并发控制
}

// GetInstance 获取Redis单例实例
func GetInstance() *Redis {
	if instance == nil {
		panic("Redis instance is not initialized")
	}
	return instance
}

// Initialize 初始化Redis连接
func InitRedis() error {
	//redis配置
	redisConfig := RedisConfig{
		Host:     config.DefaultConfig.Redis.Host,
		Port:     config.DefaultConfig.Redis.Port,
		Password: config.DefaultConfig.Redis.Password,
		DB:       config.DefaultConfig.Redis.DB,
	}

	var err error
	once.Do(func() {
		instance = &Redis{}
		err = instance.connect(redisConfig)
	})
	return err
}

// connect 建立Redis连接
func (r *Redis) connect(cfg RedisConfig) error {
	addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)

	// 创建 Redis 客户端选项
	options := &redis.Options{
		Addr:     addr,
		Password: cfg.Password, // 直接设置密码
		DB:       cfg.DB,
		OnConnect: func(cn *redis.Conn) error {
			// 连接后手动进行 AUTH
			if cfg.Password != "" {
				return cn.Auth(cfg.Password).Err()
			}
			return nil
		},
	}

	r.Client = redis.NewClient(options)

	// 测试连接
	if err := r.Client.Ping().Err(); err != nil {
		return fmt.Errorf("redis连接失败: %v", err)
	}

	return nil
}

// Close 关闭Redis连接
func (r *Redis) Close() error {
	r.mu.Lock()
	defer r.mu.Unlock()

	if r.Client != nil {
		return r.Client.Close()
	}
	return nil
}

// GetClient 获取Redis客户端实例
func (r *Redis) GetClient() *redis.Client {
	r.mu.RLock()
	defer r.mu.RUnlock()
	return r.Client
}
